module TerminalKeynote
  class KeynoteController
    attr_accessor :renderer, :keynote

    NEXT_COMMANDS = %W( \s n l k \e[C \e[6~ ).freeze
    PREVIOUS_COMMANDS = %W( b p h j \e[D \e[5~ ).freeze
    GO_FIRST_COMMANDS = %W( ^ . )
    GO_LAST_COMMANDS = %W( $ )
    GO_TO_COMMAND = 'g'
    QUIT_COMMAND = 'q'

    def initialize
      @renderer = Renderer.new
      @current_slide_number = 0
    end

    def start(keynote)
      @keynote = keynote
      loop { turn }
    end

  private

    def turn
      renderer.clear
      renderer.render_slide(@keynote.slides[@current_slide_number])
      read_command
    end

    def read_command
      case command
      when *NEXT_COMMANDS
        return if @current_slide_number == @keynote.slides.length - 1
        @current_slide_number += 1
      when *PREVIOUS_COMMANDS
        return if @current_slide_number.zero?
        @current_slide_number -= 1
      when *GO_FIRST_COMMANDS
        @current_slide_number = 0
      when *GO_LAST_COMMANDS
        @current_slide_number = @keynote.slides.length - 1
      when GO_TO_COMMAND
        @current_slide_number = go_to(@current_slide_number)
      when QUIT_COMMAND
        renderer.clear
        exit
      end
    end

    def command
      $stdin.noecho do |noecho|
        noecho.raw do |raw|
          raw.getc.tap do |command|
            if command == "\e"
              command << raw.getc
              command << raw.getc
              command << raw.getc if command =~ /[56]/
            end
          end
        end
      end
    end

  end
end
